package org.thingsboard.server.controller;

import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.video.Video;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.dao.video.VideoService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.security.model.SecurityUser;

import java.util.HashMap;
import java.util.UUID;

@RestController
@TbCoreComponent
@RequestMapping("/api/")
public class VideoController extends BaseController {
    @Autowired
    private VideoService videoService;

    @PostMapping(value = "/video")
    @ResponseBody
    public Video save(@RequestBody Video videoDto, Authentication authentication) throws ThingsboardException {
        try {
            TenantId tenantId = ((SecurityUser) authentication.getPrincipal()).getTenantId();
            videoDto.setTenantId(tenantId.getId());
            Video v = videoService.getByCamId(videoDto.getCameraId());
            sanitizeVideoFields(videoDto);
            if (v != null) {
                videoDto.setId(v.getId());
            }
            Video VideoDto = videoService.saveOrUpdate(videoDto);
            VideoDto.setId(videoDto.getId());
            sanitizeVideoFields(videoDto);
            return VideoDto;
        } catch (Exception e) {
            throw handleException(e);
        }
    }

    private void sanitizeVideoFields(Video video) {
        if (video.getName() != null) {
            video.setName(StringEscapeUtils.escapeHtml4(video.getName()));
        }
        if (video.getIp() != null) {
            video.setIp(StringEscapeUtils.escapeHtml4(video.getIp()));
        }
        if (video.getOrgName() != null) {
            video.setOrgName(StringEscapeUtils.escapeHtml4(video.getOrgName()));
        }
        if (video.getOrgCode() != null) {
            video.setOrgCode(StringEscapeUtils.escapeHtml4(video.getOrgCode()));
        }
    }

    @GetMapping("/video/list")
    public ResponseEntity list(@RequestParam int pageSize,
                               @RequestParam int page, String textSearch, Authentication authentication) throws ThingsboardException {
        try {
            SecurityUser principal = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            TenantId tenantId = principal.getTenantId();

            Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
            Sort sort = Sort.by(order);
            Pageable page1 = PageRequest.of(page, pageSize, sort);
            Page<Video> p = videoService.page(page1, textSearch, tenantId);
            HashMap m = new HashMap<>();
            m.put("data", p.getContent());
            m.put("hasNext", !p.isLast());//false
            m.put("totalElements", p.getTotalElements());//2
            m.put("totalPages", p.getTotalPages());// 1
            return ResponseEntity.ok().body(m);
        } catch (Exception e) {
            throw handleException(e);
        }
    }

    @DeleteMapping("/video/{id}")
    public ResponseEntity delById(@PathVariable UUID id) throws ThingsboardException {
        try {
            videoService.delById(id);
            return ResponseEntity.ok().build();
        } catch (Exception e) {
            throw handleException(e);
        }
    }

    @GetMapping("/video/{id}")
    public ResponseEntity getById(@PathVariable UUID id) throws ThingsboardException {
        try {
            Video r = videoService.getById(id);
            return ResponseEntity.ok().body(r);
        } catch (Exception e) {
            throw handleException(e);
        }
    }


}
